package com.duowan.cms.action.article;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.duowan.cms.common.exception.BaseCheckedException;
import com.duowan.cms.common.util.FileUtil;
import com.duowan.cms.common.util.IdManager;
import com.duowan.cms.common.util.PathUtil;
import com.duowan.cms.common.util.StringUtil;
import com.duowan.cms.dto.channel.ChannelInfo;
import com.duowan.cms.dto.user.UserInfo;
import com.duowan.cms.service.channel.ChannelService;
import com.duowan.cms.service.file.FileAdapter;
import com.duowan.cms.service.file.FileService;
import com.duowan.cms.util.FileUploadHelper;
import com.duowan.cms.util.JmagickHelper;

/**
 * 处理与文章模块相关的上传处理及上传导航
 * <p>
 * 作　　者：黄均杨
 * <p>
 * 完成日期：2012-11-19
 */
@Controller
public class ArticleUploadController {

	@Autowired
	private FileService fileService;
	
	@Autowired
	private ChannelService channelService;
	
	private static Logger logger = Logger.getLogger(ArticleUploadController.class);

	/**
	 * 导航到"上传头图iframe"页面
	 */
	@RequestMapping(value = "/article/toUploadHeadPicIframe", method = RequestMethod.GET)
	public String toUploadHeadPicIframe(HttpServletRequest request, HttpServletResponse response)
				throws IOException {
		String preHeadPic = request.getParameter("preHeadPic");
		String headPicOnLineUrl = request.getParameter("headPicOnLineUrl");
		request.setAttribute("channelId", request.getParameter("channelId"));
		request.setAttribute("articleId", request.getParameter("articleId"));
		request.setAttribute("preHeadPic", StringUtil.isEmpty(preHeadPic) ? "" : preHeadPic);
		request.setAttribute("headPicOnLineUrl", StringUtil.isEmpty(headPicOnLineUrl) ? ""
					: headPicOnLineUrl);
		return "/article/article_headpic_upload";
	}

	/**
	 * 处理上传头图
	 * 
	 * @throws BaseCheckedException
	 */
	@RequestMapping(value = "/article/uploadHeadPic", method = RequestMethod.POST)
	public void uploadHeadPic(HttpServletRequest request, HttpServletResponse response)
				throws IOException, BaseCheckedException {
		UploadInfo uploadInfo = this.upload(request, response);
		response.setContentType("text/html;charset=UTF-8");//此段代码是为了让前端JS兼容firefox
		String responseUrl = "/article/toUploadHeadPicIframe.do?channelId=" + uploadInfo.getFormFieldMap().get("channelId")
		+ "&articleId=" + uploadInfo.getFormFieldMap().get("articleId")+ "&preHeadPic="
		+ URLEncoder.encode(uploadInfo.getPicUrlOnCms(), "UTF-8")
		+ "&headPicOnLineUrl="
		+ URLEncoder.encode(uploadInfo.getPicUrlOnLine(), "UTF-8");
		response.getWriter().write(responseUrl);
//		return "redirect:/article/toUploadHeadPicIframe.do?channelId=" + channelInfo.getId()
//					+ "&articleId=" + uploadInfo.getFormFieldMap().get("articleId")+ "&preHeadPic="
//					+ URLEncoder.encode(uploadInfo.getPicUrlOnCms(), "UTF-8")
//					+ "&headPicOnLineUrl="
//					+ URLEncoder.encode(uploadInfo.getPicUrlOnLine(), "UTF-8");
	}

	@RequestMapping(value = "/article/uploadArticlePic", method = RequestMethod.GET)
	public String toUploadArticlePicIframe(HttpServletRequest request, HttpServletResponse response)
				throws IOException, BaseCheckedException {
		String articleId = request.getParameter("articleId");
		ChannelInfo channelInfo = (ChannelInfo) request.getSession().getAttribute("channelInfo");
		String channelId = channelInfo.getId();
		String picBasePath = PathUtil.getPicBasePath(channelInfo.getPicFilePath(), Long
					.parseLong(articleId));
		FileAdapter fileAdapter = new FileAdapter(picBasePath, "");
		String picOnCmsBaseUrl = PathUtil.getDomainOncms(channelId).replaceAll("http://", "") + "/"
					+ IdManager.formatIdToYM(Long.parseLong(articleId)) + "/" + articleId + "/";
		String picOnLineBaseUrl = channelInfo.getPicDomain().replaceAll("http://", "") + "/"
					+ IdManager.formatIdToYM(Long.parseLong(articleId)) + "/" + articleId + "/";
		request.setAttribute("picOnCmsBaseUrl", picOnCmsBaseUrl);
		request.setAttribute("picOnLineBaseUrl", picOnLineBaseUrl);
		request.setAttribute("channelId", channelId);
		request.setAttribute("articleId", articleId);
		request.setAttribute("listFiles", fileAdapter.listFiles());
		return "/article/article_picture_upload";
	}
	/**
	 * 获取图片列表
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws BaseCheckedException
	 */
	@RequestMapping(value = "/article/getUploadPicList", method = RequestMethod.GET)
	public void getUploadPicList(HttpServletRequest request, HttpServletResponse response)
				throws IOException, BaseCheckedException {
		String articleId = request.getParameter("articleId");
		String channelId = request.getParameter("channelId");
		ChannelInfo channelInfo = channelService.getById(channelId);
		String picBasePath = PathUtil.getPicBasePath(channelInfo.getPicFilePath(), Long
					.parseLong(articleId));
		String picOnCmsBaseUrl = PathUtil.getDomainOncms(channelId) + "/"
					+ IdManager.formatIdToYM(Long.parseLong(articleId)) + "/" + articleId + "/";
		String picOnLineBaseUrl = channelInfo.getPicDomain() + "/"
					+ IdManager.formatIdToYM(Long.parseLong(articleId)) + "/" + articleId + "/";
		FileAdapter[] fileAdapterArr = new FileAdapter(picBasePath, "").listFiles();
		logger.info("获取频道[" + channelInfo.getName() + "]图片路径[" + picBasePath + "]的图片数量:" + fileAdapterArr.length);
		StringBuilder picListBuilder = new StringBuilder();
		for (int i = 0; i < fileAdapterArr.length; i++) {
			String fileName = fileAdapterArr[i].getName();
			picListBuilder.append(picOnCmsBaseUrl +fileName +"," );
			picListBuilder.append(picOnLineBaseUrl +fileName +"," );
			picListBuilder.append(fileName+";fileSeperator;" );
		}
		response.setContentType("text/html;charset=UTF-8");//此段代码是为了让前端JS兼容firefox
		response.getWriter().write(picListBuilder.toString());
	}
	
	@RequestMapping(value = "/article/deletePic", method = RequestMethod.GET)
	public void deletePic(HttpServletRequest request,HttpServletResponse response ) throws IOException, BaseCheckedException {
	    UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo");
	    ChannelInfo channelInfo = (ChannelInfo)request.getSession().getAttribute("channelInfo");
	    String articleId = request.getParameter("articleId");
        String fileName = request.getParameter("fileName");
        String filePath = 		PathUtil.getPicBasePath(channelInfo.getPicFilePath(), Long.parseLong(articleId)) + fileName;
        logger.info(userInfo.getUserId()+"删除["+channelInfo.getName()+"]频道的文件"+filePath);
		fileService.deleteFile(filePath);
	}

	/**
	 * 处理文件上传图片
	 */
	@RequestMapping(value = "/article/uploadArticlePic", method = RequestMethod.POST)
	public void uploadArticlePic(HttpServletRequest request, HttpServletResponse response)
				throws Exception {
		UploadInfo uploadInfo = this.upload(request, response);
		String isWatermark = uploadInfo.getFormFieldMap().get("isWatermark");
		if ("on".equals(isWatermark)) {//是否勾选"加水印"
			//不能取从session中取channelInfo,会出现跨频道问题
			String channelId = uploadInfo.getFormFieldMap().get("channelId");
			ChannelInfo	channelInfo = channelService.getById(channelId);
			String errorMsg = this.mark(uploadInfo, channelInfo.getPicFilePath());
			if (!StringUtil.isEmpty(errorMsg)) {
				response.getWriter().write(errorMsg);
				return;
			}
		} 
		logger.info("处理图片上传成功");
		response.getWriter().write(uploadInfo.getPicUrlOnCms() + "," + uploadInfo.getPicUrlOnLine() + ","
					+ uploadInfo.getFileName());
	}
	/**
	 * 
	 * @param uploadInfo
	 * @param picBasePath
	 * @return 上传成功，返回空字符串；上传失败，返回错误信息；
	 */
	private String mark(UploadInfo uploadInfo , String  picBasePath) throws NumberFormatException, MagickException{
		Map<String,String> formFieldMap = uploadInfo.getFormFieldMap();
		String watermarkPic = formFieldMap.get("watermarkPic");//水印图名称
		String picPath = PathUtil.getPicBasePath( picBasePath , 
			Long.parseLong(formFieldMap.get("articleId")))  + uploadInfo.getFileName();
		String watermarkPicPath = picBasePath + "/mask/" + watermarkPic ;
		logger.info("开始为图片添加,图片路径[" + picPath +"],水印名称[" + watermarkPic +"],水印路径[" + watermarkPicPath +"]"  );
		MagickImage watermarkImage = new MagickImage(new ImageInfo(watermarkPicPath));
		MagickImage srcImage= new MagickImage(new ImageInfo(picPath));
		Dimension watermarkPicSize = watermarkImage.getDimension();
		Dimension picSize = srcImage.getDimension();
		if (watermarkPicSize.getWidth() > picSize.getWidth() 
					|| watermarkPicSize.getHeight() > picSize.getHeight() ) {//水印的宽高比原图大
			logger.info("水印的宽高比原图大 , 删除上传的图片");
			fileService.deleteFile(picPath);
			return "[error]:图片("+ uploadInfo.getFileName()+")宽或高小于水印图片";
		}else{
			String maskPosition = formFieldMap.get("maskPosition");//水印图在原图的位置
			new JmagickHelper().composit(picPath, watermarkPicPath,picPath ,JmagickHelper.MaskPosition.getInstance(Integer.parseInt(maskPosition)));
		}
	   if(watermarkImage!=null)watermarkImage.destroyImages();
	   if(srcImage!=null)srcImage.destroyImages();
		return "";
	}

	/**
	 * 获取上传水印图片信息
	 */
	@RequestMapping(value = "/article/getWaterMaskList", method = RequestMethod.GET)
	public void getWaterMaskList(HttpServletRequest request, HttpServletResponse response)
				throws Exception {
		ChannelInfo channelInfo = (ChannelInfo) request.getSession().getAttribute("channelInfo");
		String watermarkPicPath = (channelInfo.getPicFilePath() + "/mask/");
		File watermarkPicDir = new File(watermarkPicPath);
		if (!watermarkPicDir.exists()) {
			watermarkPicDir.mkdirs();
		}
		File waterMaskArr[] = watermarkPicDir.listFiles();
		logger.info("获取频道[" + channelInfo.getName() + "]水印图路径[" + watermarkPicDir.getAbsolutePath() + "]的水印图数量:" + waterMaskArr.length);
		StringBuilder waterMaskBuilder = new StringBuilder();
		for (int i = 0; i < waterMaskArr.length; i++) {
			Dimension imgSize = new MagickImage(new ImageInfo(waterMaskArr[i].getAbsolutePath()))
						.getDimension();
			waterMaskBuilder.append(waterMaskArr[i].getName() + ";infoSeperator;"
						+ imgSize.getWidth() + ";infoSeperator;" + imgSize.getHeight()
						+ ";waterMaskSeperator;");
		}
		logger.info(" 获取上传水印图片信息:" + waterMaskBuilder.toString() );
		response.setContentType("text/html;charset=UTF-8");//此段代码是为了让前端JS兼容firefox
		response.getWriter().write(waterMaskBuilder.toString());
	}

	/**
	 * 清除标签图
	 */
	@RequestMapping(value = "/article/clearHeadPic", method = RequestMethod.GET)
	public void clearHeadPic(HttpServletRequest request, HttpServletResponse response)
				throws IOException {
		String channelId = request.getParameter("channelId");
		String articleId = request.getParameter("articleId");
		String picUrl = request.getParameter("picUrl");
		fileService.deleteFileByUrl(channelId, picUrl);
		response.setContentType("text/html;charset=UTF-8");//此段代码是为了让前端JS兼容firefox
		response.getWriter().write(
			"/article/toUploadHeadPicIframe.do?channelId=" + channelId + "&articleId=" + articleId
						+ "&preHeadPic=");
	}

	private UploadInfo upload(HttpServletRequest request, HttpServletResponse response)
				throws IOException, BaseCheckedException {
		FileUploadHelper fileUploadHelper = new FileUploadHelper(request);
		List<FileItem> fileItemList = fileUploadHelper.getFileItemList();
		String articleId = fileUploadHelper.getFieldValue("articleId");
		String channelId = fileUploadHelper.getFieldValue("channelId");
		ChannelInfo channelInfo = (ChannelInfo) request.getSession().getAttribute("channelInfo");
		if (!StringUtil.isEmpty(channelId)) {
			channelInfo = channelService.getById(channelId);
		}
		String picBasePath = PathUtil.getPicBasePath(channelInfo.getPicFilePath(), Long
					.parseLong(articleId));
		logger.info("频道[" + channelInfo.getName() + "]的文章[articleId=" + articleId + "]上传文件到"
					+ picBasePath);
		try {
			String fileName = FileUtil.getRandomFileNameByFileItem(fileItemList.get(0));
			String picUrlOnCms = PathUtil.getPicUrlOnCms(channelInfo.getId(), Long
						.parseLong(articleId), fileName);
			String picUrlOnLine = PathUtil.getPicUrlOnline(channelInfo.getPicDomain(), Long
						.parseLong(articleId), fileName);
			fileService.writeFile(fileItemList.get(0), picBasePath, fileName);
				return new UploadInfo(picUrlOnCms, picUrlOnLine, fileName ,  fileUploadHelper.getFormFieldMap());
		} catch (Exception e) {
			logger.error("频道[" + channelInfo.getName() + "]的文章[articleId=" + articleId + "]上传文件出错",
				e);
			throw new BaseCheckedException("", "频道[" + channelInfo.getName() + "]的文章[articleId="
						+ articleId + "]上传文件出错");
		}
	}

	/**
	 * 处理使用UEditor上传的图片
	 * UEditor上传的图片存放在
	 */
	@RequestMapping(value = "/article/uploadPicInUEditor", method = RequestMethod.POST)
	public void uploadPicInUEditor(HttpServletRequest request, HttpServletResponse response)
				throws IOException {
		FileUploadHelper fileUploadHelper = new FileUploadHelper(request);
		ChannelInfo channelInfo = (ChannelInfo) request.getSession().getAttribute("channelInfo");
		String articleId = fileUploadHelper.getFieldValue("articleId");
		String pictitle = fileUploadHelper.getFieldValue("pictitle");
		String picBasePath = PathUtil.getPicBasePath(channelInfo.getPicFilePath(), Long
					.parseLong(articleId));
		List<FileItem> fileItemList = fileUploadHelper.getFileItemList();
		for (int i = 0; i < fileItemList.size(); i++) {
			String fileName = FileUtil.getRandomFileNameByFileItem(fileItemList.get(i));
			String state = "";
			try {
				fileService.writeFile(fileItemList.get(i), picBasePath, fileName);
				state = "SUCCESS";
			} catch (SizeLimitExceededException e) {
				state = "文件大小超出限制";
			} catch (InvalidContentTypeException e) {
				state = "请求类型ENTYPE错误";
			} catch (FileUploadException e) {
				state = "上传请求异常";
			} catch (Exception e) {
				state = "写文件时出错:未知错误";
			}
			String picUrl = PathUtil.getPicUrlOnCms(channelInfo.getId(), Long.parseLong(articleId),
				fileName);
			// response.getWriter().print("{'original':'"+ fileName
			// +"','url':'"+PathUtil.getPicUrlOnCms(channelInfo.getId() ,
			// Long.parseLong(articleId) , fileName)
			// +"','title':'"+pictitle+"','state':'"+state+"'}");
			response.getWriter().print(
				"<script>parent.check_img('文件上传完毕!','" + picUrl + "');</script> ");
		}
	}

	class UploadInfo {
		private String picUrlOnCms;
		private String picUrlOnLine;
		private String fileName;
		private Map<String,String> formFieldMap;
		
		public UploadInfo( String picUrlOnCms,
					String picUrlOnLine, String fileName,  Map<String,String> formFieldMap) {
			this.picUrlOnCms = picUrlOnCms;
			this.picUrlOnLine = picUrlOnLine;
			this.fileName = fileName;
			this.formFieldMap = formFieldMap;
		}


		public Map<String, String> getFormFieldMap() {
			return formFieldMap;
		}

		public void setFormFieldMap(Map<String, String> formFieldMap) {
			this.formFieldMap = formFieldMap;
		}

		public String getFileName() {
			return fileName;
		}

		public void setFileName(String fileName) {
			this.fileName = fileName;
		}

		public String getPicUrlOnCms() {
			return picUrlOnCms;
		}

		public void setPicUrlOnCms(String picUrlOnCms) {
			this.picUrlOnCms = picUrlOnCms;
		}

		public String getPicUrlOnLine() {
			return picUrlOnLine;
		}

		public void setPicUrlOnLine(String picUrlOnLine) {
			this.picUrlOnLine = picUrlOnLine;
		}
	}

}
